package com.github.iot.activity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatCheckBox;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.github.iot.R;
import com.github.iot.adapter.ButtonAdapter;
import com.github.iot.adapter.DoorAdapter;
import com.github.iot.adapter.LightAdapter;
import com.github.iot.bean.SendLightBean;
import com.github.iot.bean.SerialBaudBean;
import com.github.iot.dao.CommonDaoUtils;
import com.github.iot.dao.DaoUtilsStore;
import com.github.iot.dialog.DeviceListDialog;
import com.github.iot.dialog.SerialConfigDialog;
import com.github.iot.entity.Button;
import com.github.iot.entity.Door;
import com.github.iot.entity.Light;
import com.github.iot.entity.ModemErrorEntity;
import com.github.iot.entity.SerialEntity;
import com.github.iot.entity.Showcase;
import com.github.iot.entity.User;
import com.github.iot.utils.ActivityUtils;
import com.github.iot.utils.BarUtils;
import com.github.iot.utils.BusUtils;
import com.github.iot.utils.ConvertHexUtils;
import com.github.iot.utils.FastJsonUtils;
import com.github.iot.utils.FormatUtils;
import com.github.iot.utils.SharedPreferencesUtils;
import com.github.iot.utils.ToastUtils;
import com.github.iot.view.RxTitle;
import com.github.iot.view.dialogs.iface.ISimpleDialogListener;
import com.orhanobut.logger.Logger;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cn.wch.uartlib.WCHUARTManager;
import cn.wch.uartlib.callback.IModemStatus;
import cn.wch.uartlib.callback.IUsbStateChange;
import cn.wch.uartlib.chipImpl.SerialErrorType;
import cn.wch.uartlib.chipImpl.type.ChipType2;
import cn.wch.uartlib.exception.NoPermissionException;

/**
 * 展柜Activity
 *
 * @Author: 梁声洪
 * @Date: 2019/12/11 23:14
 * @Version: v1.0.0
 */
public class ShowcaseActivity extends AppCompatActivity implements ISimpleDialogListener {

    private static final int REQUEST_SIMPLE_DIALOG = 1;
    private static final int REQUEST_WIFI_DIALOG = 33;

    @BindView(R.id.rx_title)
    RxTitle mTitle;

    @BindView(R.id.iv_conn)
    AppCompatImageView mIvConn;

    @BindView(R.id.tv_wifi)
    AppCompatTextView mTvWifi;

    @BindView(R.id.tv_serial_para)
    TextView mSerialPara;

    @BindView(R.id.rl_serial)
    LinearLayout mSerialLayout;

    @BindView(R.id.tv_usb_name)
    TextView mUserName;

    @BindView(R.id.cb_dtr)
    AppCompatCheckBox mDtr;

    @BindView(R.id.cb_rts)
    AppCompatCheckBox mRtr;

    @BindView(R.id.cb_break)
    AppCompatCheckBox mBreak;

    @BindView(R.id.tv_conn)
    AppCompatTextView mConnServer;

    @BindView(R.id.door_recycler_view)
    RecyclerView mDoorRecyclerView;

    @BindView(R.id.light_recycler_view)
    RecyclerView mLightRecyclerView;

    @BindView(R.id.button_recycler_view)
    RecyclerView mButtonRecyclerView;

    @BindView(R.id.lamp_layout)
    LinearLayout mLampLayout;

    @BindView(R.id.button_layout)
    LinearLayout mButtonLayout;

    private static Showcase showcase;
    private static Queue<SendLightBean> queue = new LinkedBlockingQueue<>();

    private static CommonDaoUtils<Door> doorDaoUtils = DaoUtilsStore.getInstance().getDoorDaoUtils();
    private static CommonDaoUtils<Light> lightDaoUtils = DaoUtilsStore.getInstance().getLightDaoUtils();
    private static CommonDaoUtils<Button> buttonDaoUtils = DaoUtilsStore.getInstance().getButtonDaoUtils();

    private Set<UsbDevice> devices = Collections.synchronizedSet(new HashSet<>());

    private Thread mThread;
    private SerialEntity serialEntity = null;
    private volatile boolean running = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BarUtils.setStatusBarColor(this, R.color.colorPrimaryDark);
        setContentView(R.layout.activity_showcase);

        ButterKnife.bind(this);
        BusUtils.register(this);
        String str = getIntent().getStringExtra("showcase");
        showcase = FastJsonUtils.strToBean(str, Showcase.class);

        initView();
        initData();

        // 监测USB插拔状态
        monitorUsbState();

        // 初始化设备
        initDevice();

        mThread = new ShowcaseActivity.SendMessage();
        mThread.start();
    }

    public class SendMessage extends Thread {

        @Override
        public void run() {
            super.run();

            try {
                while (running) {
                    if (!queue.isEmpty()) {
                        try {
                            SendLightBean bean = queue.poll();
                            Light light = bean.getLight();
                            light.setProgress(bean.getProgress());
                            lightDaoUtils.update(light);

                            byte[] b = new byte[2];
                            b[0] = ConvertHexUtils.intToByte(showcase.getAddress());
                            b[1] = ConvertHexUtils.intToByte(((light.getType() - 1) * 100) + bean.getProgress());

                            UsbDevice usbDevice = devices.iterator().next();
                            WCHUARTManager.getInstance().writeData(usbDevice, 0, b, b.length, 2000);
                            Thread.sleep(10);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
                        synchronized (queue) {
                            queue.wait();
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 监测USB插拔状态
     */
    private void monitorUsbState() {

        WCHUARTManager.getInstance().setUsbStateListener(new IUsbStateChange() {

            /**
             * 设备移除
             *
             * @param device
             */
            @Override
            public void usbDeviceDetach(UsbDevice device) {
                ToastUtils.error("设备移除");
                // 设备移除
                removeReadDataDevice(device);
            }

            /**
             * 设备插入
             *
             * @param device
             */
            @Override
            public void usbDeviceAttach(UsbDevice device) {
                ToastUtils.info("设备插入");
                Logger.e("设备插入");
            }

            /**
             * 请求打开设备权限结果
             *
             * @param device
             * @param result
             */
            @Override
            public void usbDevicePermission(UsbDevice device, boolean result) {
                ToastUtils.error("请求打开设备权限结果");
                Logger.e("请求打开设备权限结果");
            }
        });
    }

    private void initDevice() {
        try {
            // 枚举符合要求的设备
            ArrayList<UsbDevice> usbDeviceArrayList = WCHUARTManager.getInstance().enumDevice();
            if (usbDeviceArrayList.isEmpty()) {
                ToastUtils.error("未发现匹配的设备");
                return;
            }

            open(usbDeviceArrayList.get(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mTitle.setLeftFinish(this);
        mTitle.setTitle(showcase.getName());

        String str = SharedPreferencesUtils.getString(this, "iot_login_user", null);
        if (null != str) {
            User user = FastJsonUtils.strToBean(str, User.class);
            if (user.getType() == 3) {
                mTitle.setRightTextVisibility(false);
            } else {
                mTitle.setRightTextOnClickListener(v -> {
                    Bundle bundle = new Bundle();
                    bundle.putString("showcase", FastJsonUtils.obj2JsonStr(showcase));
                    ActivityUtils.skipActivity(ShowcaseActivity.this, ManageShowcaseActivity.class, bundle);
                });
            }
        }

        DividerItemDecoration divider = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
        divider.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider));

        // 设置串口
        mDtr.setOnCheckedChangeListener((buttonView, isChecked) -> {
            try {
                boolean b = WCHUARTManager.getInstance().setDTR(serialEntity.getUsbDevice(), serialEntity.getSerialNumber(), isChecked);
                if (b) {
                    ToastUtils.info("设置DTR成功");
                } else {
                    ToastUtils.error("设置DTR失败");
                }
            } catch (Exception e) {
                ToastUtils.error("设置DTR失败");
            }
        });
        mRtr.setOnCheckedChangeListener((buttonView, isChecked) -> {
            try {
                boolean b = WCHUARTManager.getInstance().setRTS(serialEntity.getUsbDevice(), serialEntity.getSerialNumber(), isChecked);
                if (b) {
                    ToastUtils.info("设置RTS成功");
                } else {
                    ToastUtils.error("设置RTS失败");
                }
            } catch (Exception e) {
                ToastUtils.error(e.getMessage());
            }
        });
        mBreak.setOnCheckedChangeListener((buttonView, isChecked) -> {
            try {
                boolean b = WCHUARTManager.getInstance().setBreak(serialEntity.getUsbDevice(), serialEntity.getSerialNumber(), isChecked);
                if (b) {
                    ToastUtils.info("设置Break成功");
                } else {
                    ToastUtils.error("设置Break失败");
                }
            } catch (Exception e) {
                ToastUtils.error(e.getMessage());
            }
        });

        mDoorRecyclerView.addItemDecoration(divider);
        mDoorRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mLightRecyclerView.addItemDecoration(divider);
        mLightRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mButtonRecyclerView.addItemDecoration(divider);
        mButtonRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    /**
     * 初始化数据
     */
    private void initData() {
        String sql = "WHERE SHOWCASE_ID = ? AND STATUS = 1 ORDER BY STATUS DESC, SORT ASC";
        String sql1 = "WHERE SHOWCASE_ID = ? AND STATUS = 1 ORDER BY STATUS DESC, TYPE ASC";
        List<Door> list1 = doorDaoUtils.queryByNativeSql(sql1, new String[]{String.valueOf(showcase.getId())});
        List<Light> list2 = lightDaoUtils.queryByNativeSql(sql, new String[]{String.valueOf(showcase.getId())});
        List<Button> list3 = buttonDaoUtils.queryByNativeSql(sql, new String[]{String.valueOf(showcase.getId())});

        DoorAdapter doorAdapter = new DoorAdapter(ShowcaseActivity.this, list1);
        mDoorRecyclerView.setAdapter(doorAdapter);
        doorAdapter.setOnItemClickListener(ItemClickListener);

        LightAdapter lightAdapter = new LightAdapter(ShowcaseActivity.this, list2);
        mLightRecyclerView.setAdapter(lightAdapter);
        mLampLayout.setVisibility(!list2.isEmpty() ? View.VISIBLE : View.GONE);

        ButtonAdapter buttonAdapter = new ButtonAdapter(ShowcaseActivity.this, list3);
        mButtonRecyclerView.setAdapter(buttonAdapter);

        buttonAdapter.setOnCheckedChangeCallback(CheckedChangeCallback);
        mButtonLayout.setVisibility(!list3.isEmpty() ? View.VISIBLE : View.GONE);
    }

    /**
     * item＋item里的控件点击监听事件
     */
    private DoorAdapter.OnItemClickListener ItemClickListener = new DoorAdapter.OnItemClickListener() {

        /**
         * 关闭按钮按下事件
         *
         * @param v
         * @param position
         */
        @Override
        public void closeActionDownClick(View v, Door door, int position) {
            if (door.getType().equals("柜门")) {
                v.setBackgroundResource(R.mipmap.green_close);
            }

            if (door.getType().equals("灯箱")) {
                v.setBackgroundResource(R.mipmap.green_drop);
            }

            if (door.getType().equals("背板")) {
                v.setBackgroundResource(R.mipmap.green_pull);
            }

            byte[] b = new byte[2];
            b[0] = ConvertHexUtils.intToByte(door.getAddress());
            b[1] = ConvertHexUtils.intToByte(door.getDownClose());
            sendDoorCommand(b);
        }

        /**
         * 关闭按钮按松开事件
         *
         * @param v
         * @param position
         */
        @Override
        public void closeActionUpClick(View v, Door door, int position) {
            if (door.getType().equals("柜门")) {
                v.setBackgroundResource(R.mipmap.red_close);
            }

            if (door.getType().equals("灯箱")) {
                v.setBackgroundResource(R.mipmap.red_drop);
            }

            if (door.getType().equals("背板")) {
                v.setBackgroundResource(R.mipmap.red_pull);
            }

            byte[] b = new byte[2];
            b[0] = ConvertHexUtils.intToByte(door.getAddress());
            b[1] = ConvertHexUtils.intToByte(door.getUpClose());
            sendDoorCommand(b);
        }

        /**
         * 打开按钮按下事件
         *
         * @param v
         * @param position
         */
        @Override
        public void openActionDownClick(View v, Door door, int position) {
            // v.setBackgroundResource(R.mipmap.green_open);
            if (door.getType().equals("柜门")) {
                v.setBackgroundResource(R.mipmap.green_open);
            }

            if (door.getType().equals("灯箱")) {
                v.setBackgroundResource(R.mipmap.green_rise);
            }

            if (door.getType().equals("背板")) {
                v.setBackgroundResource(R.mipmap.green_push);
            }

            byte[] b = new byte[2];
            b[0] = ConvertHexUtils.intToByte(door.getAddress());
            b[1] = ConvertHexUtils.intToByte(door.getDownOpen());
            sendDoorCommand(b);
        }

        /**
         * 打开按钮松开事件
         *
         * @param v
         * @param position
         */
        @Override
        public void openActionUpClick(View v, Door door, int position) {
            // v.setBackgroundResource(R.mipmap.red_open);
            if (door.getType().equals("柜门")) {
                v.setBackgroundResource(R.mipmap.red_open);
            }

            if (door.getType().equals("灯箱")) {
                v.setBackgroundResource(R.mipmap.red_rise);
            }

            if (door.getType().equals("背板")) {
                v.setBackgroundResource(R.mipmap.red_push);
            }

            byte[] b = new byte[2];
            b[0] = ConvertHexUtils.intToByte(door.getAddress());
            b[1] = ConvertHexUtils.intToByte(door.getUpOpen());
            sendDoorCommand(b);
        }
    };

    private ButtonAdapter.OnCheckedChangeCallback CheckedChangeCallback = new ButtonAdapter.OnCheckedChangeCallback() {

        @Override
        public void checkedChange(Button button, Boolean checked) {
            byte[] b = new byte[2];
            b[0] = ConvertHexUtils.intToByte(showcase.getAddress());
            b[1] = ConvertHexUtils.intToByte(checked ? button.getOpen() : button.getClose());
            sendDoorCommand(b);
        }

    };

    /**
     * 下发柜门控制指令
     *
     * @param b
     */
    private void sendDoorCommand(byte[] b) {
        if (devices.isEmpty()) {
            ToastUtils.error("设备未连接，请先接入Lora模块, 点击设备扫描");
            return;
        }

        UsbDevice usbDevice = devices.iterator().next();
        if (!WCHUARTManager.getInstance().isConnected(usbDevice)) {
            ToastUtils.error("设备未连接，请先接入Lora模块, 点击设备扫描");
            return;
        }

        try {
            WCHUARTManager.getInstance().writeData(usbDevice, 0, b, b.length, 2000);
            Thread.sleep(100);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressLint("NonConstantResourceId")
    @OnClick({R.id.tv_conn, R.id.tv_set_serial})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.tv_conn:
                enumDevice();
                break;
            case R.id.tv_set_serial:
                setSerial();
                break;
            default:
                break;
        }
    }

    @Override
    public void onNegativeButtonClicked(int requestCode) {

    }

    @Override
    public void onNeutralButtonClicked(int requestCode) {

    }

    @Override
    public void onPositiveButtonClicked(int requestCode) {
        if (requestCode == REQUEST_SIMPLE_DIALOG) {
            ActivityUtils.skipActivityAndFinish(ShowcaseActivity.this, NetSettingActivity.class);
        } else if (requestCode == REQUEST_WIFI_DIALOG) {
            Intent intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
            startActivity(intent);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        initData();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        running = false;

        BusUtils.unregister(this);

        // 关闭所有连接设备
        closeAll();

        clearView();

        // System.exit(0);

        // 释放资源
        try {
            WCHUARTManager.getInstance().close(this);
        } catch (Exception e) {
            e.printStackTrace();
        }

        mThread.interrupt();
        mThread = null;
    }

    private void clearView() {
        mTitle = null;
        mIvConn = null;
        mTvWifi = null;
        mSerialPara = null;
        mSerialLayout = null;
        mUserName = null;
        mDtr = null;
        mRtr = null;
        mBreak = null;
        mConnServer = null;
        mDoorRecyclerView = null;
        mLightRecyclerView = null;
        mButtonRecyclerView = null;
        mLampLayout = null;
        mButtonLayout = null;

        showcase = null;
        serialEntity = null;

        if (!devices.isEmpty()) {
            devices.clear();
        }
        devices = null;

        if (!queue.isEmpty()) {
            queue.clear();
        }
    }

    /**
     * 设置串口参数
     */
    private void setSerial() {
        SerialConfigDialog dialog = SerialConfigDialog.newInstance(null);
        dialog.setCancelable(false);
        dialog.show(this.getSupportFragmentManager(), SerialConfigDialog.class.getName());
        dialog.setListener(data -> {
            if (setSerialParameter(serialEntity.getUsbDevice(), serialEntity.getSerialNumber(), data)) {
                mSerialPara.setText(data.toString());
                ToastUtils.info("设置成功");
            } else {
                ToastUtils.error("设置失败");
            }
        });
    }

    /**
     * 设置串口参数
     *
     * @param usbDevice
     * @param serialNumber
     * @param baudBean
     * @return
     */
    boolean setSerialParameter(UsbDevice usbDevice, int serialNumber, SerialBaudBean baudBean) {
        try {
            return WCHUARTManager.getInstance().setSerialParameter(usbDevice, serialNumber, baudBean.getBaud(), baudBean.getData(), baudBean.getStop(), baudBean.getParity(), baudBean.isFlow());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 关闭所有设备
     */
    void closeAll() {
        try {
            ArrayList<UsbDevice> usbDeviceArrayList = WCHUARTManager.getInstance().enumDevice();
            for (UsbDevice usbDevice : usbDeviceArrayList) {
                if (WCHUARTManager.getInstance().isConnected(usbDevice)) {
                    WCHUARTManager.getInstance().disconnect(usbDevice);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 枚举当前所有符合要求的设备，显示设备列表
     */
    void enumDevice() {
        try {
            // 枚举符合要求的设备
            ArrayList<UsbDevice> usbDeviceArrayList = WCHUARTManager.getInstance().enumDevice();
            if (usbDeviceArrayList.isEmpty()) {
                ToastUtils.error("未发现匹配的设备");
                return;
            }

            // 显示设备列表dialog
            DeviceListDialog deviceListDialog = DeviceListDialog.newInstance(usbDeviceArrayList);
            deviceListDialog.setCancelable(false);
            deviceListDialog.show(getSupportFragmentManager(), DeviceListDialog.class.getName());
            deviceListDialog.setOnClickListener(usbDevice -> open(usbDevice));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 从设备列表中打开某个设备
     *
     * @param usbDevice
     */
    void open(@NonNull UsbDevice usbDevice) {
        if (WCHUARTManager.getInstance().isConnected(usbDevice)) {
            ToastUtils.error("当前设备已经打开");
            return;
        }

        try {
            boolean b = WCHUARTManager.getInstance().openDevice(usbDevice);
            if (b) {
                int serialCount = WCHUARTManager.getInstance().getSerialCount(usbDevice);
                if (serialCount > 0) {
                    serialEntity = new SerialEntity(usbDevice, 0);

                    // 更新UI
                    updateUi(usbDevice);

                    // 测试连接
                    textSerial(usbDevice);

                    // 将该设备添加至已打开设备列表,在读线程ReadThread中,将会读取该设备的每个串口数据
                    addToReadDeviceSet(usbDevice);

                    registerModemStatusCallback(usbDevice);
                    registerDataCallback(usbDevice);
                }
            } else {
                ToastUtils.error("打开失败");
            }
        } catch (NoPermissionException e) {
            ToastUtils.error("没有权限打开该设备");
            requestPermission(usbDevice);
        } catch (Exception e) {
            open(usbDevice);
            Log.e("TAG", e.getMessage());
        }
    }

    /**
     * 更新UI
     *
     * @param usbDevice
     */
    void updateUi(@NonNull UsbDevice usbDevice) {
        ChipType2 chipType = WCHUARTManager.getInstance().getChipType(usbDevice);
        //mTvWifi.setText(chipType.name() + ":" + chipType.getDescription());
        mTvWifi.setText("已连接");
        mTvWifi.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary));
        mIvConn.setBackgroundResource(R.mipmap.green_wifi);

        mSerialLayout.setVisibility(View.GONE);
        mUserName.setText(usbDevice.getDeviceName());

        SerialBaudBean baud = new SerialBaudBean();
        baud.setBaud(115200);
        baud.setData(8);
        baud.setStop(1);
        baud.setParity(0);
        baud.setFlow(false);
        if (setSerialParameter(serialEntity.getUsbDevice(), serialEntity.getSerialNumber(), baud)) {
            mSerialPara.setText(baud.toString());
        } else {
            ToastUtils.error("串口参数自动设置失败");
        }
    }

    /**
     * 测试串口
     */
    void textSerial(@NonNull UsbDevice usbDevice) {
        try {
            byte[] b = new byte[2];
            b[0] = (byte) 0xAA;
            b[1] = 0x55;
            WCHUARTManager.getInstance().writeData(usbDevice, 0, b, b.length, 2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 申请读写权限
     *
     * @param usbDevice
     */
    private void requestPermission(@NonNull UsbDevice usbDevice) {
        try {
            WCHUARTManager.getInstance().requestPermission(this, usbDevice);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设备移除
     *
     * @param usbDevice
     */
    private void removeReadDataDevice(@NonNull UsbDevice usbDevice) {
        synchronized (devices) {
            devices.remove(usbDevice);
        }

        mSerialLayout.setVisibility(View.GONE);
        mTvWifi.setText("未连接");
        mTvWifi.setTextColor(ContextCompat.getColor(this, R.color.color_red));
        mIvConn.setBackgroundResource(R.mipmap.red_wifi);
    }

    /**
     * 将该设备添加至已打开设备列表,在读线程ReadThread中,将会读取该设备的每个串口数据
     *
     * @param usbDevice
     */
    private void addToReadDeviceSet(@NonNull UsbDevice usbDevice) {
        synchronized (devices) {
            devices.add(usbDevice);
        }
    }

    private void registerModemStatusCallback(UsbDevice usbDevice) {
        try {
            WCHUARTManager.getInstance().registerModemStatusCallback(usbDevice, new IModemStatus() {
                @Override
                public void onStatusChanged(int serialNumber, boolean isDCDRaised, boolean isDSRRaised, boolean isCTSRaised, boolean isRINGRaised) {
                    runOnUiThread(() -> Logger.i(usbDevice.getDeviceName() + ":" + serialNumber + ":" + isDCDRaised + ":" + isDSRRaised + ":" + isCTSRaised + ":" + isRINGRaised));
                }

                @Override
                public void onOverrunError(int serialNumber) {
                    try {
                        int count = WCHUARTManager.getInstance().querySerialErrorCount(usbDevice, serialNumber, SerialErrorType.OVERRUN);
                        runOnUiThread(() -> Logger.i(usbDevice.getDeviceName() + ":" + count + ":" + ModemErrorEntity.ErrorType.OVERRUN));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onParityError(int serialNumber) {
                    try {
                        int count = WCHUARTManager.getInstance().querySerialErrorCount(usbDevice, serialNumber, SerialErrorType.PARITY);
                        runOnUiThread(() -> Logger.i(usbDevice.getDeviceName() + ":" + count + ":" + ModemErrorEntity.ErrorType.PARITY));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFrameError(int serialNumber) {
                    try {
                        int count = WCHUARTManager.getInstance().querySerialErrorCount(usbDevice, serialNumber, SerialErrorType.FRAME);
                        runOnUiThread(() -> Logger.i(usbDevice.getDeviceName() + ":" + count + ":" + ModemErrorEntity.ErrorType.FRAME));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取数据
     *
     * @param usbDevice
     */
    private void registerDataCallback(UsbDevice usbDevice) {
        try {
            WCHUARTManager.getInstance().registerDataCallback(usbDevice, (serialNumber, buffer, length) -> {
                byte[] data = new byte[length];
                System.arraycopy(buffer, 0, data, 0, data.length);
                Logger.i("串口: " + usbDevice.getDeviceName() + ", 指令:" + FormatUtils.bytes2HexString(data));
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Bus接收
     *
     * @param bean
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(SendLightBean bean) {
        if (devices.isEmpty()) {
            ToastUtils.error("设备未连接，请先接入Lora模块, 点击设备扫描");
            return;
        }

        UsbDevice usbDevice = devices.iterator().next();
        if (!WCHUARTManager.getInstance().isConnected(usbDevice)) {
            ToastUtils.error("设备未连接，请先接入Lora模块, 点击设备扫描");
            return;
        }

        queue.offer(bean);
        synchronized (queue) {
            queue.notify();
        }
    }

}